package com.huaxin.hxmoduleworkorder.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huaxin.hxmoduleworkorder.common.annotation.validation.ValidMaintenanceOrderOperation;
import com.huaxin.hxmoduleworkorder.common.annotation.validation.ValidMaintenanceOrderOperatorRole;
import com.huaxin.hxmoduleworkorder.common.enums.MaintenanceOrderOperation;
import com.huaxin.hxmoduleworkorder.common.enums.MaintenanceOrderOperatorRole;
import com.huaxin.hxmoduleworkorder.dto.ResponseResult;
import com.huaxin.hxmoduleworkorder.dto.request.*;
import com.huaxin.hxmoduleworkorder.dto.response.MaintenanceOrderDetailRespDto;
import com.huaxin.hxmoduleworkorder.models.MaintenanceOrder;
import com.huaxin.hxmoduleworkorder.models.MaintenanceOrderProcess;
import com.huaxin.hxmoduleworkorder.service.MaintenanceOrderProcessService;
import com.huaxin.hxmoduleworkorder.service.MaintenanceOrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Tag(name = "维保工单", description = "工单的增删改查及流程操作")
@RestController
@RequiredArgsConstructor
@RequestMapping("/v1/workorder/maintenanceOrder")
public class MaintenanceOrderController {

    private final MaintenanceOrderService service;
    private final MaintenanceOrderProcessService processService;

    /* *********************************************************************
     * 工单基础 CRUD
     ********************************************************************* */

    @Operation(summary = "创建维修工单", description = "由客户、电工或管理员发起")
    @PostMapping("/create")
    public ResponseResult<MaintenanceOrder> create(@RequestBody @Valid MaintenanceOrderCreateReqDTO in) {
        return service.create(in);
    }

    @Operation(summary = "根据工单ID获取工单基本信息", description = "根据工单ID获取工单基本信息")
    @GetMapping("/get")
    public ResponseResult<MaintenanceOrder> getOrderById(@Parameter(description = "工单ID", example = "m_order_001") @RequestParam(value = "id", required = true) String id) {
        return ResponseResult.ok(service.getOrderById(id));
    }

    @Operation(summary = "更新工单基础信息", description = "仅限未分配前可编辑")
    @PostMapping("/update")
    public ResponseResult<String> update(@RequestBody @Valid MaintenanceOrderUpdateReqDTO in) {
        return service.update(in);
    }

    @Operation(summary = "删除工单", description = "管理员可删除已驳回或已取消的工单")
    @PostMapping("/delete")
    public ResponseResult<String> delete(@RequestBody @Valid MaintenanceOrderDeleteReqDto in) {
        return service.delete(in);
    }

    /* *********************************************************************
     * 状态与流程管理
     ********************************************************************* */

    @Operation(summary = "获取工单状态", description = "获取工单状态")
    @GetMapping("/getStatus")
    public ResponseResult<String> getOrderStatus(@Parameter(description = "工单ID", example = "m_order_001") @RequestParam(value = "id", required = true) String id) {
        return service.getOrderStatus(id);
    }

    @Operation(summary = "获取可执行操作列表", description = "获取可执行操作列表")
    @GetMapping("/availableOperations")
    public ResponseResult<List<String>> getAvailableOperations(@Parameter(description = "工单ID", example = "m_order_001")
                                                               @RequestParam(value = "id", required = true)
                                                               String id,
                                                               @Parameter(description = "操作人角色，允许值：customer/admin/electrician", example = "customer")
                                                               @RequestParam(value = "operatorRole", required = true)
                                                               @ValidMaintenanceOrderOperatorRole
                                                               String operatorRole) {
        List<MaintenanceOrderOperation> operations = service.getAvailableOperations(id, MaintenanceOrderOperatorRole.of(operatorRole));
        List<String> operationCodes = operations.stream().map(MaintenanceOrderOperation::getCode).toList();
        return ResponseResult.ok(operationCodes);
    }

    @Operation(summary = "检查是否允许执行某操作", description = "检查是否允许执行某操作")
    @GetMapping("/canOperate")
    public ResponseResult<Boolean> canOperate(@Parameter(description = "工单ID", example = "m_order_001")
                                              @RequestParam(value = "id", required = true)
                                              String id,
                                              @Parameter(description = "操作，允许值：reviewing/reassign/processing/resolve/evaluate/complete/reject/rollback/cancel/view/edit/delete", example = "reviewing")
                                              @RequestParam(value = "action", required = true)
                                              @Valid @ValidMaintenanceOrderOperation
                                              String action,
                                              @Parameter(description = "操作人角色，允许值：customer/admin/electrician", example = "customer")
                                              @RequestParam(value = "operatorRole", required = true)
                                              @Valid @ValidMaintenanceOrderOperatorRole
                                              String operatorRole) {
        return ResponseResult.ok(service.canOperate(id, MaintenanceOrderOperation.of(action), MaintenanceOrderOperatorRole.of(operatorRole)));
    }

    @Operation(summary = "工单审核通过", description = "执行工单审核通过")
    @PostMapping("/review")
    public ResponseResult<String> review(@RequestBody @Valid MaintenanceOrderReviewReqDto in) {
        return service.review(in);
    }

    @Operation(summary = "驳回工单", description = "执行工单驳回")
    @PostMapping("/reject")
    public ResponseResult<String> reject(@RequestBody @Valid MaintenanceOrderRejectReqDto in) {
        return service.reject(in);
    }

    @Operation(summary = "工单回退", description = "工单回退")
    @PostMapping("/rollback")
    public ResponseResult<String> rollback(@RequestBody @Valid MaintenanceOrderRollbackReqDto in) {
        return service.rollback(in);
    }

    @Operation(summary = "重新分配电工", description = "重新分配电工，处理拒单或调整电工")
    @PostMapping("/reassign")
    public ResponseResult<String> reassign(@RequestBody @Valid MaintenanceOrderAssignReqDto in) {
        return service.reassign(in);
    }

    @Operation(summary = "工单处理完成", description = "工单处理完成")
    @PostMapping("/complete")
    ResponseResult<String> complete(@RequestBody @Valid MaintenanceOrderCompleteReqDto in) {
        return service.complete(in);
    }

    @Operation(summary = "取消工单", description = "取消工单")
    @PostMapping("/cancel")
    public ResponseResult<String> cancel(@RequestBody @Valid MaintenanceOrderCancelReqDto in) {
        return service.cancel(in);
    }

    /* *********************************************************************
     * 流程记录
     ********************************************************************* */

    @Operation(summary = "获取工单流程历史", description = "获取工单流程历史")
    @GetMapping("/processHistory")
    public ResponseResult<List<MaintenanceOrderProcess>> getProcessHistory(@Parameter(description = "工单ID", example = "m_order_001") @RequestParam(value = "id", required = true) String id) {
        return ResponseResult.ok(processService.getProcessHistory(id));
    }

    /* *********************************************************************
     * 分页与条件查询
     ********************************************************************* */

    @Operation(summary = "获取分页列表", description = "获取分页列表")
    @PostMapping("/page")
    public ResponseResult<Page<MaintenanceOrder>> pageQuery(@RequestBody @Valid MaintenanceOrderPageListReqDTO in) {
        return service.pageQuery(in);
    }

    @Operation(summary = "获取工单详情", description = "获取工单详情")
    @GetMapping("/detail")
    public ResponseResult<MaintenanceOrderDetailRespDto> detail(@Parameter(description = "工单ID", example = "m_order_001") @RequestParam(value = "id", required = true) String id) {
        return ResponseResult.ok(service.detail(id));
    }

    /* *********************************************************************
     * 统计与报表
     ********************************************************************* */

    @Operation(summary = "获取工单状态统计", description = "统计各状态工单数量")
    @GetMapping("/stats/status-count")
    public ResponseResult<Map<String, Long>> countByStatus() {
        return service.countByStatus();
    }

    @Operation(summary = "获取工单时间范围统计", description = "统计指定时间范围内的工单数量")
    @GetMapping("/stats/range-count")
    public ResponseResult<Long> countInRange(@Parameter(description = "开始时间", example = "2023-01-01T00:00:00") @RequestParam(value = "startTime", required = true) LocalDateTime startTime,
                                             @Parameter(description = "结束时间", example = "2023-02-01T00:00:00") @RequestParam(value = "endTime", required = true) LocalDateTime endTime) {
        return service.countInRange(startTime, endTime);
    }

    @Operation(summary = "获取工单逾期列表", description = "获取超时未处理的工单")
    @GetMapping("/overdue")
    public ResponseResult<List<MaintenanceOrder>> listOverdueOrders(@Parameter(description = "超时阈值（小时）", example = "24") @RequestParam(value = "thresholdHours", required = true, defaultValue = "24") Long thresholdHours) {
        return service.listOverdueOrders(thresholdHours);
    }

    /* *********************************************************************
     * 系统
     ********************************************************************* */
    @Operation(summary = "同步工单状态", description = "同步工单状态")
    @GetMapping("/syncStatus")
    public ResponseResult<String> syncStatus(@Parameter(description = "工单ID", example = "m_order_001") @RequestParam(value = "id", required = true) String id) {
        service.syncOrderStatus(id);
        return ResponseResult.ok("同步成功");
    }
}